import requests
import time
import json
import os
from datetime import datetime

# 配置
GET_OPERATION_LIST_URL = 'https://csb-api.gz.cvte.cn/wfp-api/v1/wfp/api/wf/ext/getOperationList'
APPROVE_PROCESS_URL = 'https://csb-api.gz.cvte.cn/wfp-api/v1/wfp/api/wf/ext/approveProcess'
DRAFTER_ACCOUNT = 'dscm_admin'   # 查询任务ID时使用的账号

# 文件名
INPUT_FILE = 'document_ids.txt'  # 输入的单据ID列表文件
PROCESSED_FILE = 'processed.txt'  # 已处理的ID记录文件
ERROR_FILE = 'errorList.txt'      # 处理失败的ID记录文件
POSITION_FILE = 'position.txt'    # 记录处理位置的文件
LOG_FILE = 'process.log'          # 日志文件


def log_message(message):
    """
    记录日志
    """
    timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    log_entry = f"[{timestamp}] {message}"
    print(log_entry)
    
    with open(LOG_FILE, 'a', encoding='utf-8') as f:
        f.write(log_entry + '\n')


def get_task_id(form_instance_id):
    """
    查询单据的任务ID
    """
    headers = {
        'Content-Type': 'application/json',
        'Cookie': 'BIGipServerpool_yp_ingress_nginx_dev_it=2620265738.26745.0000'
    }
    
    data = {
        "formInstanceId": form_instance_id,
        "handlerAccount": DRAFTER_ACCOUNT
    }
    
    try:
        response = requests.post(GET_OPERATION_LIST_URL, headers=headers, data=json.dumps(data), timeout=30)
        response.raise_for_status()
        result = response.json()
        
        if result.get('status') == '0' and result.get('data'):
            # 获取第一个任务的ID
            task_data = result['data'][0]
            task_id = task_data.get('taskId')
            activity_type = task_data.get('activityType')
            return task_id, activity_type
        else:
            error_msg = f"获取任务ID失败，单据ID: {form_instance_id}, 响应: {result}"
            log_message(error_msg)
            return None, None
    except Exception as e:
        error_msg = f"查询任务ID时发生异常，单据ID: {form_instance_id}, 错误: {e}"
        log_message(error_msg)
        return None, None


def abandon_document(form_instance_id, task_id, activity_type):
    """
    作废单据
    """
    headers = {
        'Content-Type': 'application/json'
    }
    
    data = {
        "formInstanceId": form_instance_id,
        "handlerAccount": DRAFTER_ACCOUNT,
        "processParam": {
            "activityType": activity_type,
            "operationType": "admin_abandon",
            "taskId": task_id
        }
    }
    
    try:
        response = requests.post(APPROVE_PROCESS_URL, headers=headers, data=json.dumps(data), timeout=30)
        response.raise_for_status()
        result = response.json()
        
        if result.get('status') == '0':
            return True
        else:
            error_msg = f"作废单据失败，单据ID: {form_instance_id}, 响应: {result}"
            log_message(error_msg)
            return False
    except Exception as e:
        error_msg = f"作废单据时发生异常，单据ID: {form_instance_id}, 错误: {e}"
        log_message(error_msg)
        return False


def read_processed_ids():
    """
    读取已处理的ID列表
    """
    if not os.path.exists(PROCESSED_FILE):
        return set()
    
    try:
        with open(PROCESSED_FILE, 'r', encoding='utf-8') as f:
            return set(line.strip() for line in f if line.strip())
    except Exception as e:
        log_message(f"读取已处理ID文件失败: {e}")
        return set()


def save_processed_id(form_instance_id):
    """
    保存已处理的ID
    """
    try:
        with open(PROCESSED_FILE, 'a', encoding='utf-8') as f:
            f.write(form_instance_id + '\n')
    except Exception as e:
        log_message(f"保存已处理ID失败: {form_instance_id}, 错误: {e}")


def save_error_id(form_instance_id, error_message=""):
    """
    保存处理失败的ID
    """
    try:
        with open(ERROR_FILE, 'a', encoding='utf-8') as f:
            if error_message:
                f.write(f"{form_instance_id} - {error_message}\n")
            else:
                f.write(form_instance_id + '\n')
    except Exception as e:
        log_message(f"保存错误ID失败: {form_instance_id}, 错误: {e}")


def save_position(position):
    """
    保存处理位置
    """
    try:
        with open(POSITION_FILE, 'w', encoding='utf-8') as f:
            f.write(str(position))
    except Exception as e:
        log_message(f"保存处理位置失败: {e}")


def read_position():
    """
    读取处理位置
    """
    if not os.path.exists(POSITION_FILE):
        return 0
    
    try:
        with open(POSITION_FILE, 'r', encoding='utf-8') as f:
            return int(f.read().strip())
    except Exception as e:
        log_message(f"读取处理位置失败: {e}")
        return 0


def process_documents():
    """
    主处理函数
    """
    if not os.path.exists(INPUT_FILE):
        log_message(f"输入文件 {INPUT_FILE} 不存在")
        return
    
    # 读取已处理的ID
    processed_ids = read_processed_ids()
    log_message(f"已处理的单据数量: {len(processed_ids)}")
    
    # 读取处理位置
    start_position = read_position()
    log_message(f"开始处理位置: {start_position}")
    
    # 读取所有单据ID
    try:
        with open(INPUT_FILE, 'r', encoding='utf-8') as f:
            document_ids = [line.strip() for line in f if line.strip()]
    except Exception as e:
        log_message(f"读取单据ID文件失败: {e}")
        return
    
    total_count = len(document_ids)
    log_message(f"总单据数量: {total_count}")
    
    if total_count == 0:
        log_message("没有需要处理的单据")
        return
    
    # 从指定位置开始处理
    processed_count = 0
    success_count = 0
    error_count = 0
    
    for i in range(start_position, total_count):
        form_instance_id = document_ids[i]
        
        # 跳过已处理的ID
        if form_instance_id in processed_ids:
            log_message(f"跳过已处理的单据: {form_instance_id}")
            save_position(i + 1)
            continue
        
        processed_count += 1
        log_message(f"正在处理第 {i+1}/{total_count} 个单据: {form_instance_id}")
        
        # 查询任务ID
        task_id, activity_type = get_task_id(form_instance_id)
        if not task_id:
            log_message(f"获取任务ID失败: {form_instance_id}")
            save_error_id(form_instance_id, "获取任务ID失败")
            save_position(i + 1)
            error_count += 1
            continue
        
        # 作废单据
        success = abandon_document(form_instance_id, task_id, activity_type)
        if success:
            log_message(f"作废成功: {form_instance_id}")
            save_processed_id(form_instance_id)
            success_count += 1
        else:
            log_message(f"作废失败: {form_instance_id}")
            save_error_id(form_instance_id, "作废接口调用失败")
            error_count += 1
        
        # 保存处理位置
        save_position(i + 1)
        
        # 每秒处理一个
        if i < total_count - 1:  # 最后一个不需要等待
            time.sleep(1)
    
    log_message(f"处理完成。总计: {processed_count}, 成功: {success_count}, 失败: {error_count}")


if __name__ == "__main__":
    log_message("程序开始执行")
    try:
        process_documents()
    except KeyboardInterrupt:
        log_message("程序被用户中断")
    except Exception as e:
        log_message(f"程序执行出错: {e}")
    finally:
        log_message("程序执行结束")